package com.jinzhi.jzapi.common.controller;

import com.alibaba.fastjson.JSONObject;
import com.jinzhi.api.exception.IFastApiException;
import com.jinzhi.common.annotation.Log;
import com.jinzhi.common.base.BaseController;
import com.jinzhi.common.service.DictService;
import com.jinzhi.common.type.ApiEnumError;
import com.jinzhi.common.utils.*;
import com.jinzhi.jzapi.utils.DataEnum;
import com.jinzhi.jzweb.domain.ChapterDO;
import com.jinzhi.jzweb.domain.MessageplatfromDO;
import com.jinzhi.jzweb.service.ChapterService;
import com.jinzhi.jzweb.service.MessageplatfromService;
import com.jinzhi.oss.service.FileService;
import com.jinzhi.oss.service.OssService;
import com.jinzhi.sms.support.SmsManager;
import com.jinzhi.sys.domain.UserDO;
import com.jinzhi.sys.domain.UserRoleDO;
import com.jinzhi.sys.service.UserRoleService;
import com.jinzhi.sys.service.UserService;
import com.jinzhi.wxmp.domain.MpConfigDO;
import com.jinzhi.wxmp.service.MpConfigService;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.authz.annotation.RequiresAuthentication;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.math.BigDecimal;
import java.util.*;

import static com.jinzhi.api.util.TokenTag.TOKEN_TAG;


@Slf4j
@RestController
@RequestMapping("/jzApi/utils")
public class ApiUtilsController extends BaseController {
    @Autowired
    private FileService fileService;
    @Autowired
    private DictService dictService;
    @Autowired
    private SmsManager smsSerevice;
    @Autowired
    private UserService userService;
    @Autowired
    private UserRoleService userRoleService;
    @Autowired
    private MpConfigService mpConfigService;
    @Autowired
    private MessageplatfromService messageplatfromService;
    @Autowired
    private OssService ossService;
    @Autowired
    private ChapterService chapterService;
    private static final String T_REG_SMS_PREFIX = "TRAINING_REG_";//培训端
    private static final String C_REG_SMS_PREFIX = "CERTIFICATE_REG_";//证书端
    private static final String O_REG_SMS_PREFIX = "ORTHER_REG_";//其他端
    private static BigDecimal bigDecimal;

    static {
        bigDecimal = new BigDecimal(100);
    }

    //授权（必填）
    String grant_type = DataEnum.wx_grant_type.getValue();

    //微信url
    String wx_url = DataEnum.wx_authorization_url.getValue();

    /**
     * api小程序端-文件上传接口
     *
     * @Description: 文件上传，参数：文件
     * @Param: [file]
     * @return: com.jinzhi.common.utils.ApiResult<?>
     * @Author: kl
     * @Date: 2020-03-05
     */
    @PostMapping("/fileImprot")
    @Log("api小程序端-文件上传接口")
    @ApiOperation(value = "api小程序端-文件上传接口", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    @Transactional
    public ApiResult<?> fileImprot(@RequestParam("file") MultipartFile file) {
        String url = "";

       // Random myrd = new Random();

       // Long date = new Date().getTime();

      //  String name = file.getOriginalFilename().substring(0, file.getOriginalFilename().indexOf("."));
       // String str2 = file.getOriginalFilename().substring(name.length() + 1, file.getOriginalFilename().length());

       // String fileName = file.getOriginalFilename().replace(file.getOriginalFilename(), date.toString()) + myrd.nextInt(1000) + "." + str2;

            url = ossService.uploadFileOss(file);

        return ApiResult.success("上传成功", url);
    }


    /**
     * api小程序端-文件上传接口
     *
     * @Description: 文件上传，参数：文件
     * @Param: [file]
     * @return: com.jinzhi.common.utils.ApiResult<?>
     * @Author: kl
     * @Date: 2020-03-09
     */
    @PostMapping("/fileImprot1")
    @Log("api小程序端-文件上传接口")
    @ApiOperation(value = "api小程序端-文件上传接口", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    @Transactional
    public Result<String> fileImprot1(@RequestParam("file") MultipartFile file) {
        if (file.isEmpty()) {
            return Result.build(501, "文件为空");
        }
        String url = "";
        //url = fileService.upload(file);
        url = ossService.uploadFileOss(file);
        return Result.ok(url);
    }


    /**
     * api小程序端-关于平台数据接口--公开方法，不需要登录
     *
     * @Description: 关于平台信息查询
     * @Param: []
     * @return: com.jinzhi.common.utils.ApiResult<?>
     * @Author: kl
     * @Date: 2020-03-04
     */
    @GetMapping("/selAboutUs")
    @Log("api小程序端-关于平台数据接口")
    @ApiOperation(value = "api小程序端-关于平台数据接口", httpMethod = "GET", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    @Transactional
    public ApiResult<?> selAboutUs() {
        Map returnMaps = new HashMap();
        Map<String, String> map = new HashMap<>();
        map.put("name", "关于平台");
        map.put("type", "aboutUs");
        List<Map> maps = dictService.selTypeNameVue(map);
        returnMaps.put("aboutUs", maps);
        return ApiResult.success(returnMaps);
    }

    /**
     * 证书门户端-忘记密码
     *
     * @Description: 证书门户端用户忘记密码操作，更改新密码；参数：手机号码，验证码，新密码
     * @Param: [mobile, code ,newPassWord]
     * @return: com.jinzhi.common.utils.ApiResult<?>
     * @Author: kl
     * @Date: 2020-03-14
     */
    @GetMapping("/forgetPassWord")
    @Log("证书门户端-忘记密码")
    @ApiOperation(value = "证书门户端-忘记密码", httpMethod = "GET", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    @Transactional
    public ApiResult<?> forgetPassWord(String mobile, String code, String newPassWord) {
        if (StringUtils.isBlank(code)) {
            return ApiResult.lack("code");
        } else {
            //判断验证码
            try {
                smsSerevice.verify(O_REG_SMS_PREFIX, mobile, code);
            } catch (Exception e) {
                return ApiResult.build(ApiEnumError.apiSmsCodeInvalid.getCode(), ApiEnumError.apiSmsCodeInvalid.getMsg());
            }

            UserDO userDO = userService.findOneByKv("mobile", mobile);
            if (userDO != null) {
                String salt = UUIDUtils.get();
                String encodePasswd = PasswdUtils.get(newPassWord, salt);
                userDO.setSalt(salt);
                userDO.setPassword(encodePasswd);

                List<Long> list = new ArrayList<>();
                list.add(56L);
                userDO.setroleIds(list);
                boolean b = userService.updateById(userDO);
                if (b) {
                    return ApiResult.success();
                }
            } else {
                return ApiResult.build(ApiEnumError.NOUSERERROR.getCode(), ApiEnumError.NOUSERERROR.getMsg());
            }
        }
        return ApiResult.fail();
    }

    @PostMapping("/sendPassWordCode")
    @Log("发送修改密码验证短信")
    @ApiOperation(value = "发送修改密码验证短信", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    @ResponseBody
    public ApiResult<?> sendPassWordCode(String wxId, String mobile) {
        //第一步验证手机号格式
        if (StringUtils.isBlank(mobile)) {
            return ApiResult.lack("mobile");
        }
        if (!ValidUtils.isMobile(mobile)) {
            return ApiResult.format("mobile");
        }

        //第二步发送短信，错误信息由方法直接返回
        Object smsDemo = EhCacheUtil.get("修改密码验证");
        if(smsDemo == null){
            MessageplatfromDO messageplatfromDO = messageplatfromService.findOneByKv("修改密码验证");
            if(messageplatfromDO != null){
                EhCacheUtil.put("修改密码验证",messageplatfromDO.getSmsDemo());
                if (wxId.equals("101")) {
                    smsSerevice.sendPassword(C_REG_SMS_PREFIX, mobile,messageplatfromDO.getSmsDemo());
                } else if (wxId.equals("102")) {
                    smsSerevice.sendPassword(T_REG_SMS_PREFIX, mobile,messageplatfromDO.getSmsDemo());
                } else {
                    smsSerevice.sendPassword(O_REG_SMS_PREFIX, mobile,messageplatfromDO.getSmsDemo());
                }
            }else{
                return ApiResult.fail("短信模板错误，请联系管理员！");
            }
        }else{
            if (wxId.equals("101")) {
                smsSerevice.sendPassword(C_REG_SMS_PREFIX, mobile,(String) smsDemo);
            } else if (wxId.equals("102")) {
                smsSerevice.sendPassword(T_REG_SMS_PREFIX, mobile,(String) smsDemo);
            } else {
                smsSerevice.sendPassword(O_REG_SMS_PREFIX, mobile,(String) smsDemo);
            }
        }

        return ApiResult.success("发送成功");
    }


    @Log("选择课程对应章节")
    @ResponseBody
    @GetMapping("/byCourToChapList")
    @ApiOperation(value = "选择课程对应章节", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public Result<?> distributionSecond(String coursesId) {
        if (StringUtils.isNotBlank(coursesId)) {
            List<Map<Object, Object>> mapsre = new ArrayList<>();
            //只查询最上级的知识点
            List<ChapterDO> chapterDOS = chapterService.findByKv("courses_id", Long.parseLong(coursesId), "state", 0);
            if (chapterDOS != null && chapterDOS.size() > 0) {
                for (ChapterDO chapterDO : chapterDOS) {
                    Map map = new HashMap();
                    map.put("id", chapterDO.getId());
                    map.put("name", chapterDO.getName());
                    mapsre.add(map);
                }
            }

            return Result.ok(mapsre);

        }
        return Result.fail("请先选择课程！");
    }

    @PostMapping("/savaOpenId")
    @Log("api小程序端-保存openId")
    @ApiOperation(value = "api小程序端-保存openId", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    @Transactional
    @RequiresAuthentication
    @ApiImplicitParams({@ApiImplicitParam(name = TOKEN_TAG, value = TOKEN_TAG, paramType = "header")})
    public ApiResult<?> savaOpenId(@RequestHeader(value = TOKEN_TAG, required = false) String token,Integer wxId,String code) {
        //1.根据token获取用户登录数据
        UserDO user = this.getClientUser(token);
        if (null == user) {
            return ApiResult.invalid();
        }
        //登录凭证不能为空
        if (StringUtils.isBlank(code)) {
            return ApiResult.lack("code");
        }
        MpConfigDO mpConfigDO = mpConfigService.selectById(wxId);
        if (null == mpConfigDO) {
            throw new IFastApiException(ApiEnumError.getConfFail.getCodeStr());
        }
        //请求参数
        String params = "appid=" + mpConfigDO.getAppId() + "&secret=" + mpConfigDO.getAppSecret() + "&js_code=" + code + "&grant_type=" + grant_type;
        //发送请求
        String sr = HttpRequest.sendGet(wx_url, params);
        //解析相应内容（转换成json对象）
        JSONObject json = JSONObject.parseObject(sr);
        String errcode = null;
        if (null != json.get("errcode")) {
            errcode = json.get("errcode").toString();
        }
        if (StringUtils.isNotBlank(errcode)) {
            String errmsg = json.getString("errmsg");
            return ApiResult.build(ApiEnumError.wxThrowFail.getCode(), "微信错误码：" + errcode + "\n" + "微信错误信息：" + errmsg);
        }

        //用户的唯一标识（openid）
        String openid = json.getString("openid");
        if (wxId.equals(101)) {
            user.setCerOpenId(openid);//证书小程序openId
        } else if (wxId.equals(102)) {
            user.setTraOpenId(openid);//培训小程序openId
        }
        List<Long> roleIds = new ArrayList<>();
        //编辑用户信息时，记得添加角色信息，否则或导致后期角色错误
        List<UserRoleDO> userRoleDO = userRoleService.findByKv("userId", user.getId());
        if (userRoleDO != null && userRoleDO.size() > 0) {
            for (int i = 0; i < userRoleDO.size(); i++) {
                roleIds.add(userRoleDO.get(i).getRoleId());
            }
        } else {
            roleIds.add(56L);
        }
        user.setroleIds(roleIds);
        boolean b = userService.updateById(user);
        if(b){
            return ApiResult.success();
        }else{
            return ApiResult.fail();
        }
    }

}
